use alloc::string::String;
use core::mem::offset_of;

use super::current::current_mut;
use crate::boot::{init_stack_end, KERNEL_DS};

pub struct Task {
    name: String,
    stack: usize,
    thread_addr_limit: usize,
    thread_flags: u32,
    thread_preempt_count: u32,
}

pub const TSK_STACK: usize = offset_of!(Task, stack);
pub const TSK_TI_ADDR_LIMIT: usize = offset_of!(Task, thread_addr_limit);
pub const TSK_TI_FLAGS: usize = offset_of!(Task, thread_flags);
pub const TSK_TI_PREEMPT: usize = offset_of!(Task, thread_preempt_count);

impl Task {
    pub fn name(&self) -> &str {
        &self.name
    }

    pub fn stack(&self) -> usize {
        self.stack
    }
}

#[no_mangle]
pub static INIT_TASK: Task = Task {
    name: String::new(),
    stack: 0,
    thread_addr_limit: KERNEL_DS,
    thread_flags: 0,
    thread_preempt_count: 0,
};

pub fn task_init() {
    let init = current_mut();
    init.name = String::from("swapper");
    init.stack = init_stack_end();
}
